home *** CD-ROM | disk | FTP | other *** search
/ NetNews Offline 2 / NetNews Offline Volume 2.iso / news / comp / lang / c++-part1 / 8494 < prev    next >
Encoding:
Internet Message Format  |  1996-08-05  |  4.0 KB

  1. Path: moalla.trin.cam.ac.uk!93bb
  2. From: 93bb@eng.cam.ac.uk (Ben Blaukopf)
  3. Newsgroups: comp.lang.pascal.misc,comp.lang.c++,comp.lang.c,comp.lang.pascal.borland
  4. Subject: Re: Tough FACTORIAL math problem...
  5. Date: Thu, 15 Feb 1996 18:07:23
  6. Organization: University of Cambridge, England
  7. Message-ID: <93bb.5.00122006@eng.cam.ac.uk>
  8. References: <4fr8be$ass@news.iconn.net> <31224679.6193@born.com> <4fv74c$chq@gatekeeper.alcatel.no>
  9. NNTP-Posting-Host: moalla.trin.cam.ac.uk
  10. X-Newsreader: Trumpet for Windows [Version 1.0 Rev A]
  11.  
  12. In article <4fv74c$chq@gatekeeper.alcatel.no> Sven.Pran@alcatel.no (Sven Pran) writes:
  13. >From: Sven.Pran@alcatel.no (Sven Pran)
  14. >Subject: Re: Tough FACTORIAL math problem...
  15. >Date: Thu, 15 Feb 96 11:50:11 GMT
  16.  
  17. >In article <31224679.6193@born.com>, John Cleland <clelaj@born.com> wrote:
  18. >>The Crow wrote:
  19. >>> 
  20. >>> Here is what I am trying to do, I want to find the last NON-ZERO digit of a
  21. >>> given factorial.  For instance,
  22. >>> 
  23. >>> 5! = 120
  24. >>> 
  25. >>> so the last non-zero digit is 2.  I want to be able to do this up to 1000.
  26. >>> Problem is, no matter how huge of a data-type you use, there isn't any way 
  27. >>> for the computer to handle 1000!, it is however possible to find the last 
  28. >>> non-zero digit somehow.  One thing I have tried is as I went through 
  29. >>> multiplying the series of numbers in the factorial (5 * 4 * 3 * 2) I would 
  30. >>> remove all the trailing ZEROS, I got this to work up to 789, but it wont 
  31. >>> work with 1000 and i am not really sure why.  If anyone has a clue how I 
  32. >>> can do this let me know.
  33. >>
  34. >>Don't just strip the trailing zeros, remove all digits except the last 
  35. >>non-zero digit (which is your output) and then multiply by the next number in 
  36. >>your sequence. This keeps the numbers down to a managable level and gives the 
  37. >>correct answer as no more significant digit can affect the value of the LSD.
  38. >>
  39. > . . . .
  40.  
  41. >No, it is obviously not sufficient to keep the last single non-zero digit, and 
  42. >the problem appears to be a very interesting and intriguing one:
  43.  
  44. >A new trailing zero is 'created' every time the next multiplier is divisible 
  45. >by 5, and how can we then calculate the next 'rightmost significant' digit?
  46.  
  47. >Example when a multiplier ends in 05:
  48.  
  49. >If the 'previous' factorial ended in 02 then the new factorial will end in 1 
  50. >while if it ended in 12 then the new factorial will end in 6 (after removal of 
  51. >trailing zeroes).
  52.  
  53. >Thus the SINGLE rightmost significant digit in the new factorial depends upon 
  54. >the TWO rightmost significant digits both in the previous factorial and in the 
  55. >multiplier.
  56.  
  57. >This means that we must keep track of the last TWO digits to calculate the new 
  58. >SINGLE rightmost significant digit whenever a zero is 'created'. For similar 
  59. >reasons we must track THREE digits to calculate the new TWO rightmost 
  60. >significant digits - and so on.
  61.  
  62. >How many zeroes have been 'removed' when we reach 1000! ? The answer is 249, 
  63. >which means that in order to maintain the precision needed we must track the 
  64. >last 250 digits less the number of zeroes already 'removed' when N! reaches a 
  65. >number with that many digits.
  66.  
  67. >This is where I get stuck. Hey - number theory specialists: How do we proceed?
  68.  
  69. >regards Sven
  70. Since we are programming this, rather than it being a pure maths problem, 
  71. there are a lot of shortcuts we can look out for.
  72.  
  73. of each number in the factorial, only the rightmost digit is significant, so 
  74. for example 85 is equivalent to 5.
  75.  
  76. so 85! is equivalent to (10!)^8 * 5!
  77. but of course only the right-hand few digits of 10! are at all significant.
  78.  
  79. 1.9 = 9 (right most non-zero digit)
  80. 9.8 = 2
  81. 2.7 = 4
  82. 4.6 = 4
  83. 4.5 = 2
  84. 2.4 = 8
  85. 8.3 = 4
  86. 4.2 = 8
  87. 8.1 = 8
  88.  
  89. So (10a+b)! = 8^a * b! (when dealing with least significant non-zero digit)
  90.  
  91. 8.8 = 64 (10!)
  92. 4.8 = 32 (20!)
  93. 2.8 = 16 (30!)
  94. 6.8 = 48 (40!)
  95.  
  96. therefore the whole thing cycles round every forty digits. note that this does 
  97. not mean that the last digit of 45! is the same as that of 5!, you have to 
  98. reach 10!. So 50! is equivalent to 10!, and all numbers up - (50+a)! is 
  99. equivalent to (10+a)!.
  100.  
  101. This should help!!!
  102.  
  103. Ben Blaukopf 
  104. 93bb@eng.cam.ac.uk 
  105.